﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Xml;
using bmapi.HelperClass;
using bmapi.Models.DataEntity;
using Ionic.Zip;

namespace bmapi.Controllers
{
    [Route("import")]
    public class ImportDataController : PageController
    {
        private List<SQLCommand> m_cmds = new List<SQLCommand>();//插入语句集合 

        /// <summary>
        /// 数据导入  
        /// </summary> 
        /// <param name="obj"></param>
        [HttpPost]
        public HttpResponseMessage ImportDataPost(dynamic obj)
        {
            User currenUser = GetUserByLoginID(GetCrrentIDByToken());
            if (currenUser == null)
                return AssistFun.toJson(new { status = 201, tip = "不合法用户" });
            int year_moth = DateTime.Now.Year * 100 + DateTime.Now.Month;
            try
            {
                #region 参数
                int isModel = Convert.ToInt32(obj.model);
                int saveModel = 0;
                string type = obj.type.ToString();
                string brand = obj.brand.ToString();
                string sex = obj.sex.ToString();
                #endregion

                string stylePath = m_buyiRoot + "\\buyiStyle\\" + year_moth;
                if (!Directory.Exists(stylePath))
                    Directory.CreateDirectory(stylePath);
                stylePath += "\\";
                string userPath = m_buyiRoot + "\\buyiUpload\\" + currenUser.login_id;
                if(!Directory.Exists(userPath))
                    return AssistFun.toJson(new { status = 201, tip = "未能找到导入文件"});
                DirectoryInfo folder = new DirectoryInfo(userPath);
                int allStyle = folder.GetDirectories().Length;
                int modelnameCount = 0;
                //获取存储模式 
                foreach (DirectoryInfo item in folder.GetDirectories())
                {
                    saveModel = GetSaveModel(item.FullName + "\\" + item.Name + ".model");
                    break;
                }                
                //遍历所有子目录   
                foreach (DirectoryInfo item in folder.GetDirectories())
                {                    
                    m_cmds.Clear();
                    List<string> modelName = new List<string>();
                    if (saveModel == 0)
                        modelName = GetModelName(item);//普通模式,遍历prj文件,获得样式名
                    else
                    {
                        //加法模式或减法模式,在model文件内获得样式信息  
                        string modelFie = item.FullName + "\\" + item.Name + ".model";
                        modelName = GetModelNamesByXml(modelFie);
                    }  
                    string oldyearMoth= GetStyleYearMoth(item.Name);                    
                    string oldstyle = m_buyiRoot + "\\buyiStyle\\" + oldyearMoth;
                    WriteLog("ImportDataPost", "oldstyle:" + oldstyle);
                    if (oldyearMoth != null && Directory.Exists(oldstyle))
                    {
                        //重新导入的款式的存储模式是否一致
                         if(!IsSameSaveModel(item.Name,saveModel))
                            return AssistFun.toJson(new { status = 201, tip = "新的导入款与已有款的存储模式不一致" });
                        //判断是否包含已有款式中的所有样式
                        if (!MathNewOldMiselName(item.Name, modelName))
                            return AssistFun.toJson(new { status = 201, tip = "新的导入数据中必须包括已存在的样式信息" });
                        WriteLog("ImportDataPost", "已经存在款式文件进行覆盖操作" + oldstyle);
                        DeleteFolder(oldstyle);
                        stylePath = oldstyle.Substring(0, oldstyle.LastIndexOf("\\") + 1);
                        item.MoveTo(stylePath + item.Name);
                        if (!InsertData(item, modelName, isModel, type, brand, sex, saveModel, currenUser, true))
                        {
                            DirectoryInfo src = new DirectoryInfo(stylePath + item.Name);
                            src.MoveTo(item.FullName);
                        }
                        else
                            modelnameCount += modelName.Count;
                    }
                    else
                    {
                        WriteLog("ImportDataPost", "新建款式");
                        if (CheckStylename(item.Name))
                            return AssistFun.toJson(new { status = 201, tip = "款式名" + item.Name + "不能重复" });
                        //向数据库,插入数据,里面有异常处理    
                        item.MoveTo(stylePath + item.Name);
                        if (!InsertData(item, modelName, isModel, type, brand, sex, saveModel, currenUser))
                        {
                            DirectoryInfo src = new DirectoryInfo(stylePath + item.Name);
                            src.MoveTo(item.FullName);
                        }
                        else
                            modelnameCount += modelName.Count;
                    }
                }
                return RespondImportInfo(folder, allStyle, modelnameCount);
            }
            catch (Exception e)
            {
                WriteLog("ImportDataPost", e.Message);
                return AssistFun.toJson(new { status = 201, tip = "错误详情请看日志" + e.Message });
            }
        }
        
        /// <summary>
        /// 上传款式文件  
        /// </summary>
        [HttpPost,Route("uploadstyle"),JwtAuthActionFilter]
        public HttpResponseMessage UploadStyle()
        {
            try
            {
                HttpPostedFile file = HttpContext.Current.Request.Files["file"];
                HttpPostedFileBase uploadfile = new HttpPostedFileWrapper(file) as HttpPostedFileBase;
                if (uploadfile == null)
                    return AssistFun.toJson(new { status = 201, tip = "no:请选择文件" });
                if (uploadfile.FileName == "")
                    return AssistFun.toJson(new { status = 201, tip = "no:请选择文件,fileup:" + file.FileName });
                HttpContext context = HttpContext.Current;
                //取得文件的扩展名,并转换成小写 
                string fileExtension = Path.GetExtension(uploadfile.FileName).ToLower();
                if (!fileExtension.Equals(".zip"))
                    return AssistFun.toJson(new { status = 201, tip = "请选择ZIP格式的压缩文件" });
                int year_moth = DateTime.Now.Year * 100 + DateTime.Now.Month;
                string userPath = m_buyiRoot + "\\buyiUpload\\" + GetCrrentIDByToken();
                if (!Directory.Exists(userPath))
                    Directory.CreateDirectory(userPath);                

                //存储路径
                string dir = userPath + "\\" + uploadfile.FileName;
                dir = dir.ToLower();
                string rootPath = HttpContext.Current.Server.MapPath("/");
                string readDir = Path.GetDirectoryName(dir);
                if (!Directory.Exists(readDir))
                    Directory.CreateDirectory(readDir);
                DeleteFolderTest(userPath);
                //保存文件
                uploadfile.SaveAs(dir);
                
                //解压缩    
                return UnZip(dir, userPath);                
            }
            catch (Exception ex)
            {
                return AssistFun.toJson(new { status = 201, tip = "异常:"+ex.Message }); 
            }
            
        }
        #region 解压      
        /// <summary> 
        /// 解压功能(解压压缩文件到指定目录) 
        /// </summary> 
        /// <param name="fileToUnZip">待解压的文件</param> 
        /// <param name="zipedFolder">指定解压目标目录</param> 
        /// <param name="password">密码(暂无)</param> 
        /// <returns>解压结果</returns> 
        private HttpResponseMessage UnZip(string fileToUnZip, string zipedFolder)
        {
            try
            {
                using (ZipFile zip = new ZipFile(fileToUnZip, Encoding.Default))
                {
                    zip.ExtractAll(zipedFolder, ExtractExistingFileAction.OverwriteSilently);
                }
                File.Delete(fileToUnZip);
            }
            catch (Exception ex)
            {
                return AssistFun.toJson(new { status = 201, tip = "异常:"+ex.Message });

            }           
            return AssistFun.toJson(new { status = 200, tip = "成功" });
        }

        #endregion

        /// <summary>
        /// 删除文件夹下的所有文件  
        /// </summary>
        /// <param name="dirPath"></param>
        private void DeleteFolderTest(string dirPath)
        {
            if (Directory.Exists(dirPath))
            {
                foreach (string content in Directory.GetFileSystemEntries(dirPath))
                {
                    if (Directory.Exists(content))
                    {
                        Directory.Delete(content, true);
                    }
                    else if (File.Exists(content))
                    {
                        File.Delete(content);
                    }
                }
            }
        }

        /// <summary>
        /// 获取存储模式
        /// </summary>
        /// <param name="modelPath"></param>
        /// <returns></returns>
        private int GetSaveModel(string modelPath)
        {
            int saveModel = 0;
            try
            {
                XmlDocument xmldoc = new XmlDocument();
                xmldoc.Load(modelPath);
                //获取xml文件中的样式名
                //获取节点列表 
                XmlNodeList model = xmldoc.SelectSingleNode("modelTable").ChildNodes;
                string modelstr = model[model.Count - 2].InnerText;
                if (modelstr != null && modelstr != "")
                    saveModel = Convert.ToInt32(modelstr);
            }
            catch (Exception) //数据转换出错   记录存储模式的节点数据类型不符
            {
                saveModel = 0;
            }       
           
            return saveModel; 
        }

        /// <summary>
        /// 重新导入的款式的存储模式是否一致
        /// </summary>
        /// <returns></returns>
        private bool IsSameSaveModel(string name,int savemodel)
        {
            SQLCommand sc = new SQLCommand("select save_model from Style_tb where name=@stylename", "@stylename", name);
            string res = sc.ExecuteScalar();
            if (Convert.ToInt32(res) != savemodel)
                return false;
            return true;
        }
        /// <summary>
        /// 比较新的样式文件中是否包含已存在的样式信息
        /// </summary>
        /// <param name="sid"></param>
        /// <param name="modelName"></param>
        /// <returns></returns>
        private bool MathNewOldMiselName(string stylename,List<string> modelName)
        {
            SQLCommand sc = new SQLCommand("select style_id from Style_tb where name=@stylename", "@stylename", stylename);
            int sid = Convert.ToInt32(sc.ExecuteScalar());
            sc = new SQLCommand("select name from Model_tb where style_id=@sid", "@sid", sid);
            DataTable dt = sc.ExecuteScalars();
            if (dt == null)
                return false;
            List<string> oldModelName = (dt).AsEnumerable().Select(d => d.Field<string>("name")).ToList();
            
            return oldModelName.All(o => modelName.Any(a => a.Equals(o)));
        }

        private List<string> GetModelName(DirectoryInfo styleDir)
        {
            //样式名  
            List<string> files = new List<string>();
            foreach (FileInfo file in styleDir.GetFiles("*.prj"))
            {
                string filename = file.Name;
                files.Add(filename.Substring(0, filename.Length - 4));
            }
            return files;
        }

        /// <summary>
        /// 根据.model文件获取款下的样式
        /// </summary>   
        /// <param name="xmlPath"></param>
        /// <returns></returns>
        private List<string> GetModelNamesByXml(string xmlPath)
        {
            List<string> files = new List<string>();
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(xmlPath);
            //获取xml文件中的样式名
            //获取节点列表 
            XmlNodeList model = xmldoc.SelectNodes("//model");
            foreach (XmlElement ele in model)
            {
                string txt = ele.GetElementsByTagName("name")[0].InnerText;
                if (!string.IsNullOrEmpty(txt))
                    files.Add(txt);
            }
            return files;
        }

        private bool InsertData(DirectoryInfo styleDir, List<string> modelName, int isModel, string type, string brand, string sex, int savemodel, User user,bool isOldStyle=false)
        {
            DirectoryInfo A3 = new DirectoryInfo(styleDir.FullName + "\\A3");
            try
            {                                
                if (!isOldStyle)
                {
                    int styleid = GetNewSafeID(user.login_id);
                    AddCmdForStyle(styleid, isModel, styleDir.Name, type, brand, sex, user.login_id, savemodel);
                    AddCmdForModel(user, modelName, styleid, A3);
                }
                else
                {
                    string sql = "select style_id from Style_tb where name=@name";
                    SQLCommand sc = new SQLCommand(sql, "@name", styleDir.Name);
                    int sid = Convert.ToInt32(sc.ExecuteScalar());                    
                    List<string> newModelName = new List<string>();
                    for (int i = 0; i < modelName.Count; i++)
                    {
                        if (!CheckModelname(modelName[i],sid))
                            newModelName.Add(modelName[i]);
                    }
                    AddCmdForModel(user, newModelName, sid, A3);
                }
                if (m_cmds.Count == 0)  //重新导入的款中样式信息一致
                    return true;
                if (SQLCommand.ExecTran(m_cmds) > 0)
                    return true;
            }
            catch (Exception e)
            {
                WriteDebug("InsertData", e.Message);
                WriteLog("InsertData", e.Message);
            }
            return false;
        }
        /// <summary>
        /// 查询样式名是否存在
        /// </summary>
        /// <param name="modelName">样式名</param>
        /// <returns></returns>
        private bool CheckModelname(string modelName, int sid)
        {
            try
            {
                string sql = "select name from Model_tb where name=@name and style_id=@styleid";
                SQLCommand sc = new SQLCommand(sql);
                sc.Add("@name", modelName);
                sc.Add("@styleid", sid);
                if (sc.ExecuteScalar() == null)
                    return false;
                else
                    return true;
            }
            catch (Exception e)
            {
                WriteLog("CheckModelname", e.Message);
                return false;
            }
        }
        /// <summary>
        /// 插入style_tb命令
        /// </summary>
        /// <param name="filenames"></param>
        /// <param name="isModel"></param>
        /// <param name="styleName"></param>
        /// <param name="brand"></param>
        /// <param name="sex"></param>
        private void AddCmdForStyle(int styleId, int isModel, string styleName, string type, string brand, string sex, int login_id, int savemodel)
        {
            SQLCommand sc = new SQLCommand("insert into Style_tb values(@styleid,@stylename,@model,@save,@type,@brand,@sex,@styleTime)");
            sc.Add("@styleid", styleId);
            sc.Add("@stylename", styleName);
            sc.Add("@model", isModel);
            sc.Add("@save", savemodel);
            sc.Add("@type", type);
            sc.Add("@brand", brand);
            sc.Add("@sex", sex);
            sc.Add("@styleTime", DateTime.Now.Year * 100 + DateTime.Now.Month);
            m_cmds.Add(sc);
        }
        /// <summary>
        /// 修改style_tb命令  待用  暂时没有需求
        /// </summary>  改品类是考虑正在被使用
        /// <param name="filenames"></param>
        /// <param name="isModel"></param>
        /// <param name="styleName"></param>
        /// <param name="brand"></param>
        /// <param name="sex"></param>
        private void UpdateCmdForStyle(int styleId, int isModel, string type, string brand, string sex, int savemodel)
        {
            SQLCommand sc = new SQLCommand("update Style_tb set is_model=@model,save_model=@save,type=@type,brand=@brand,sex=@sex where style_id=@styleid");            
            sc.Add("@model", isModel);
            sc.Add("@save", savemodel);
            sc.Add("@type", type);            
            sc.Add("@sex", sex);
            sc.Add("@brand", brand);
            sc.Add("@styleid", styleId);
            m_cmds.Add(sc);
        }
        /// <summary>
        /// 插入Model_tb命令
        /// </summary> 
        /// <param name="currenUser">当前用户</param>
        /// <param name="styleId">款id</param>
        /// <param name="path">模板文件路径</param>
        private int AddCmdForModel(User currenUser, List<string> modelName, int styleId, DirectoryInfo A3)
        {
            //插入model_tb数据  对应有几个模板文件就有多少条记录 
            SQLCommand sc = null;
            string sql = "insert into Model_tb values(";
            for (int i = 0; i < modelName.Count; i++)
            {
                int modelid = GetNewSafeID(currenUser.login_id);

                string imgName = "";

                //获取图片名
                if (A3.Exists)
                {
                    imgName = modelName[i] + ".jpg";
                    if (!File.Exists(A3.FullName + "\\" + imgName))
                    {
                        imgName = modelName[i] + ".png";
                        if (!File.Exists(A3.FullName + "\\" + imgName))
                            imgName = "";
                    }
                }
                sc = new SQLCommand();
                sc.AddInsert("@modelidid", modelid);
                sc.AddInsert("@modelname", modelName[i]);
                sc.AddInsert("@creater", currenUser.login_id);
                sc.AddTimeInsert("@time", DateTime.Now);
                if (!string.IsNullOrEmpty(imgName))
                {
                    imgName = (A3.FullName + "\\" + imgName).ToLower();
                    imgName = imgName.Remove(0,imgName.LastIndexOf("buyiroot"));
                }
                sc.AddInsert("@img", imgName);
                sc.AddInsert("@sid", styleId);
                sc.AddInsert("@plid", currenUser.PLID);
                sc.AddInsert("@pod", 0); 
                sc.AddInsert("@state", 2);
                sc.JoinSql(sql);

                m_cmds.Add(sc);

                TaskCmd(currenUser, modelid);
            }
            return 0;
        }

        /// <summary>
        /// 插入Task_tb命令
        /// </summary> 
        /// <param name="currenUser"></param>
        /// <param name="id">根据工序编码判断是MODEL.ID还是ORDER.ID  工序编码<33的就是model.Id </param>
        private void TaskCmd(User currenUser, int id)
        {
            SQLCommand sc = null;
            sc = new SQLCommand("insert into Task_tb(id,user_id,code) values(@tid, @userid, @code)");
            sc.Add("@tid", id);
            sc.Add("@userid", currenUser.login_id);
            sc.Add("@code", 1);
            m_cmds.Add(sc);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="folder">文件移动后的用户目录 </param>
        /// <param name="styleCount">总的款式</param>
        /// <param name="modelCount">总的样式</param>
        /// <returns></returns>
        private HttpResponseMessage RespondImportInfo(DirectoryInfo folder, int styleCount, int modelCount)
        {
            int userCount = folder.GetDirectories().Length;
            int failCount = styleCount - userCount;
            if (userCount == 0)
                return AssistFun.toJson(new { status = 200, tip = "导入" + styleCount + "个款," + modelCount + "个样式" });
            else
                return AssistFun.toJson(new { status = 201, tip = "还剩" + (userCount == styleCount ? userCount : failCount) + "个款未导入" });
        }

        #region  测试
        [HttpGet, Route("testim")]
        public void Test()
        {
            string imgPath = @"C:\Users\Administrator\Desktop\11\test";

            DeleteFolder(imgPath);

            //int sumLength = imgPath.Length; 
            //int s = imgPath.LastIndexOf('\\');
            //int e = imgPath.LastIndexOf('.');
            //string imf = Path.GetFileNameWithoutExtension(imgPath);
            //string path = AssistFun.buyiRoot + "\\buyiUpload\\1123";
            //List<string> imgpath = new List<string>();
            //DirectoryInfo folder = new DirectoryInfo(path);
            //foreach (DirectoryInfo dir in folder.GetDirectories())
            //{
            //    DirectoryInfo a3 = new DirectoryInfo(dir.FullName);
            //    foreach (DirectoryInfo file in a3.GetDirectories())
            //    {
            //        if (file.Name.Contains("A3")) 
            //        {
            //            DirectoryInfo a3img = new DirectoryInfo(file.FullName);
            //            foreach (FileInfo f in a3img.GetFiles())
            //            {
            //                imgpath.Add(UrlConvertor(f.FullName));
            //            }
            //        }
            //    }
            //}  
            //imf = Path.GetFileNameWithoutExtension(imgpath[0]);

            //urlPath = urlPath.Replace(@"\", @"/");  
            //return urlPath;

            //string xmlPath = @"D:\joint\HaiLan\文档\model\test.xml";
            //List<string> files = new List<string>();
            //XmlDocument xmldoc = new XmlDocument();
            //xmldoc.Load(xmlPath);
            ////获取xml文件中的样式名
            ////获取节点列表 
            //XmlNodeList model = xmldoc.SelectNodes("//model");
            //foreach (XmlElement ele in model)
            //{
            //    files.Add(ele.GetElementsByTagName("name")[0].InnerText);
            //}

            //MoveFolder(userPath, @"C:\Users\Administrator\Desktop\2\a");
            //DirectoryInfo folder = new DirectoryInfo(userPath);
            //List<string> dirs = new List<string>();

            //Hashtable ht = new Hashtable();            
            //foreach (var item in folder.GetDirectories())
            //{
            //    dirs.Add(item.Name);
            //    DirectoryInfo filefolder = new DirectoryInfo(item.FullName);
            //    List<string> files = new List<string>();
            //    foreach (var file in filefolder.GetFiles())
            //    {
            //        string filename = file.Name;
            //        files.Add(filename.Substring(0, filename.LastIndexOf(".")));
            //    }
            //    ht.Add(item.Name, files);
            //}
            //List<string> modelName = new List<string>();

            //foreach (DictionaryEntry de in ht)
            //{
            //    modelName = de.Value as List<string>;
            //}
        }
        #endregion
    }
}
